package cn.iocoder.boot.ThreadPool;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程池配置类，用于创建和管理自定义线程池。
 * 通过 Spring 的 @Bean 注解，将线程池定义为一个 Bean，使其可以在 Spring 容器中被其他组件使用。
 */
@Configuration
public class ThreadPoolConfig {
    /**
     * 线程池核心线程数，表示线程池中始终保持的线程数量。
     * 这些线程会在任务提交时立即执行，即使任务队列中有空闲空间。设置为 5 表示线程池初始化时会启动 5 个线程。
     */
    private static final int CORE_POOL_SIZE = 5;
    /**
     * 线程池最大线程数，表示线程池中允许的最大线程数量。
     * 当任务队列已满时，线程池会继续创建新线程直到达到这个数量。设置为 10 表示线程池最多可以创建 10 个线程来处理任务。
     */
    private static final int MAX_POOL_SIZE = 10;
    /**
     * 线程池维护线程所允许的空闲时间，表示线程在空闲状态下可以保持的最长时间。
     * 如果一个线程空闲时间超过这个值，它将被终止，以释放系统资源。设置为 60 秒表示线程在空闲 60 秒后会被终止。
     */
    private static final int KEEP_ALIVE_SECONDS = 60;
    /**
     * 线程池所使用的缓冲队列容量，用于存储等待执行的任务。
     * 当任务提交时，如果线程池中的线程已经全部忙于执行任务，新任务会被添加到这个队列中等待。
     * 设置为 100 表示队列最多可以存储 100 个等待执行的任务。
     */
    private static final int QUEUE_CAPACITY = 100;
    /**
     * 定义一个 ExecutorService Bean，名称为 "taskExecutor"。
     * 这个 Bean 是一个线程池，用于执行异步任务。使用 @Bean 注解使其可以在 Spring 容器中被其他组件注入和使用。
     *
     * @return 配置好的 ExecutorService 线程池实例
     */
    @Bean("taskExecutor")
    public ExecutorService executorService() {
        // 使用 AtomicInteger 来生成线程名称的计数器，确保每个线程都有唯一的名称
        AtomicInteger c = new AtomicInteger(1);
        // 创建一个 LinkedBlockingQueue 作为线程池的任务队列，指定容量为 QUEUE_CAPACITY
        LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(QUEUE_CAPACITY);
        // 创建线程池实例
        return new ThreadPoolExecutor(
                CORE_POOL_SIZE, // 核心线程数
                MAX_POOL_SIZE, // 最大线程数
                KEEP_ALIVE_SECONDS, // 空闲线程存活时间
                TimeUnit.SECONDS, // 时间单位
                queue, // 任务队列
                // 自定义线程工厂，用于设置线程名称
                r -> new Thread(r, "itheima-pool-" + c.getAndIncrement()),
                // 设置拒绝策略为 DiscardPolicy，当线程池已满且无法接收新任务时，直接丢弃新任务
                new ThreadPoolExecutor.DiscardPolicy()
        );
    }
}




